// Copyright 2012, Vanya Davidenko.
// Используемая кодировка: UTF-8.

#ifndef LIBV_TESTS_BOOST_PARSE_H_
#define LIBV_TESTS_BOOST_PARSE_H_

#include <gtest/gtest.h>
#include <boost/rational.hpp>
#include <libv/boost/parse.h>
#include <libv/check.h>



namespace libv {
namespace tests {

typedef boost::rational<int64_t> R;

TEST(ParseRationalTests, Error) {
    EXPECT_THROW(ParseRational(""), libv::PrecondException);
    EXPECT_THROW(ParseRational("."), libv::VerifyException);
    EXPECT_THROW(ParseRational("1..5"), ::std::exception);

    EXPECT_THROW(ParseRational("1.+5"), libv::VerifyException);
    EXPECT_THROW(ParseRational("1.-"), libv::VerifyException);

    EXPECT_THROW(ParseRational("1E.5"), libv::VerifyException);

    EXPECT_THROW(ParseRational("1e"), libv::VerifyException);
    EXPECT_THROW(ParseRational("1a5"), ::std::exception);
    EXPECT_THROW(ParseRational("1e*5"), ::std::exception);
    EXPECT_THROW(ParseRational("1ee5"), ::std::exception);
    EXPECT_THROW(ParseRational(".E"), libv::VerifyException);
    EXPECT_THROW(ParseRational("+.E0"), libv::VerifyException);

    EXPECT_THROW(ParseRational("12345678901234567890"), libv::VerifyException);
    EXPECT_THROW(ParseRational("1.0E123456"), libv::VerifyException);
}

TEST(ParseRationalTests, Integer) {
    EXPECT_EQ(R(0), ParseRational("0"));
    EXPECT_EQ(R(1), ParseRational("1"));
    EXPECT_EQ(R(666), ParseRational("666"));
    EXPECT_EQ(R(-123), ParseRational("-123"));

    EXPECT_EQ(R(0), ParseRational("+0"));
    EXPECT_EQ(R(0), ParseRational("-0"));
    EXPECT_EQ(R(1), ParseRational("+1"));
    EXPECT_EQ(R(-1), ParseRational("-1"));
}

TEST(ParseRationalTests, SimpleFloat) {
    EXPECT_EQ(R(1), ParseRational("1.0"));
    EXPECT_EQ(R(-25, 2), ParseRational("-12.5"));
    EXPECT_EQ(R(1, 8), ParseRational("+0.125"));
}

TEST(ParseRationalTests, FloatFirstPoint) {
    EXPECT_EQ(R(0), ParseRational("+.0"));
    EXPECT_EQ(R(-1, 10), ParseRational("-.1"));
    EXPECT_EQ(R(1, 8), ParseRational(".125"));
}

TEST(ParseRationalTests, FloatLastPoint) {
    EXPECT_EQ(R(0), ParseRational("0."));
    EXPECT_EQ(R(-1), ParseRational("-1."));
    EXPECT_EQ(R(125), ParseRational("125."));
}

TEST(ParseRationalTests, FloatExp) {
    EXPECT_EQ(R(0), ParseRational("0E0"));
    EXPECT_EQ(R(-10), ParseRational("-1E1"));
    EXPECT_EQ(R(5, 4), ParseRational("125E-2"));
    EXPECT_EQ(R(-10000000000LL), ParseRational("-1E10"));

    EXPECT_EQ(R(0), ParseRational("0e0"));
    EXPECT_EQ(R(-10), ParseRational("-1e1"));
    EXPECT_EQ(R(5, 4), ParseRational("125e-2"));
    EXPECT_EQ(R(-10000000000LL), ParseRational("-1e10"));
}

TEST(ParseRationalTests, FloatZerosAtEnd) {
    EXPECT_EQ(R(10000), ParseRational(".10E5"));
    EXPECT_EQ(R(10000), ParseRational(".100E5"));

    EXPECT_EQ(R(0), ParseRational(".0"));
    EXPECT_EQ(R(1, 10), ParseRational(".100"));
    EXPECT_EQ(R(1, 10), ParseRational(".100000"));
}

TEST(ParseRationalTests, Complex) {
    EXPECT_EQ(R(100000), ParseRational("1.E5"));
    EXPECT_EQ(R(10000), ParseRational(".1E5"));

    EXPECT_EQ(R(1, 1000000), ParseRational(".10E-5"));
    EXPECT_EQ(R(-1, 1000000), ParseRational("-.100E-5"));

    EXPECT_EQ(R(1, 1000000), ParseRational("+.1E-5"));
    EXPECT_EQ(R(10000), ParseRational("+.1E+5"));

    EXPECT_EQ(R(12312500), ParseRational("123.125E+5"));
    EXPECT_EQ(R(123125), ParseRational("123.125E+3"));
    EXPECT_EQ(R(1246250, 2), ParseRational("123.125E+2"));
}

}  // testring
}  // libv

#endif  // LIBV_TESTS_BOOST_PARSE_H_